const { connectMongoDB, closeMongoDB } = require('./util')
const Neo4j = require('node-neo4j')

// 将节点类型与关系类型存入MongoDB
const saveNodeAndRelationTypesToMongoDB = (username, nodeTypes, relationTypes) => {
  return new Promise(async resolve => {
    const { client, dbo } = await connectMongoDB()
    const where = { username }
    dbo.collection('user').updateOne(where, {
      $set: {
        "cg.nodeTypes": nodeTypes,
        "cg.relationTypes": relationTypes
      }
    }).then(() => {
      closeMongoDB(client)
      resolve()
    })
  })
}

// 从MongoDB中获取节点类型
const getNodeTypesByMongoDB = username => {
  return new Promise(async resolve => {
    const { client, dbo } = await connectMongoDB()
    const where = { username }
    dbo.collection('user').find(where).toArray((err, res) => {
      if (err) throw err
      const data = res[0].cg.nodeTypes
      resolve(data)
      closeMongoDB(client)
    })
  })
}

// 从MongoDB中获取关系类型
const getRelationTypesByMongoDB = username => {
  return new Promise(async resolve => {
    const { client, dbo } = await connectMongoDB()
    const where = { username }
    dbo.collection('user').find(where).toArray((err, res) => {
      if (err) throw err
      const data = res[0].cg.relationTypes
      resolve(data)
      closeMongoDB(client)
    })
  })
}

// 判断节点类型是否存在
const isExistNodeType = (username, newType) => {
  return new Promise(async resolve => {
    const { client, dbo } = await connectMongoDB()
    const where = { username }
    dbo.collection('user').find(where).toArray((err, res) => {
      const nodeTypes = res[0].cg.nodeTypes
      resolve(nodeTypes.includes(newType))
      closeMongoDB(client)
    })
  })
}

// 新增节点类型
const addNodeType = (username, newType) => {
  return new Promise(async resolve => {
    const { client, dbo } = await connectMongoDB()
    const where = { username }
    dbo.collection('user').updateOne(where, {
      $push: {
        "cg.nodeTypes": newType
      }
    }).then(() => {
      closeMongoDB(client)
      resolve()
    })
  })
}

// 判定关系类型是否存在
const isExistRelationType = (username, newType) => {
  return new Promise(async resolve => {
    const { client, dbo } = await connectMongoDB()
    const where = { username }
    dbo.collection('user').find(where).toArray((err, res) => {
      const relationTypes = res[0].cg.relationTypes
      resolve(relationTypes.includes(newType))
      closeMongoDB(client)
    })
  })
}

// 添加关系类型
const addRelationType = (username, newType) => {
  return new Promise(async resolve => {
    const { client, dbo } = await connectMongoDB()
    const where = { username }
    dbo.collection('user').updateOne(where, {
      $push: {
        "cg.relationTypes": newType
      }
    }).then(() => {
      resolve()
      closeMongoDB(client)
    })
  })
}

// 根据类型获取节点数量
const getNodeCountByNodeType = ({ url }, nodeType) => {
  return new Promise(resolve => {
    const neo = new Neo4j(url)
    const cql = `MATCH (N:${nodeType}) RETURN COUNT(N) AS TOTAL_N`
    neo.cypherQuery(cql, (err, res) => {
      if (err) throw err
      const data = res.data[0]
      resolve(data)
    })
  })
}

// 根据类型获取关系数量
const getRelationCountByNodeType = ({ url }, relationType) => {
  return new Promise(resolve => {
    const neo = new Neo4j(url)
    const cql = `MATCH ()-[R:${relationType}]->() RETURN COUNT(R) AS TOTAL_R`
    neo.cypherQuery(cql, (err, res) => {
      if (err) throw err
      const data = res.data[0]
      resolve(data)
    })
  })
}

module.exports = {
  saveNodeAndRelationTypesToMongoDB, // 从知识图谱中同步节点类型与关系类型到MongoDB中
  getNodeTypesByMongoDB, // 从mongodb中获取节点类型
  getRelationTypesByMongoDB, // 从mongodb中获取关系类型
  isExistNodeType, // 判断节点类型是否已经存在
  addNodeType, // 添加节点类型
  isExistRelationType, // 判定关系类型是否已经存在
  addRelationType, // 添加关系类型
  getNodeCountByNodeType, // 根据类型获取节点的数量
  getRelationCountByNodeType, // 根据类型获取关系数量
}